﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Web;
using System.Windows.Forms;
using CloudClip.Clip;
using CloudClip.ExtensionMethod;
using CloudClip.HelperMehtod;
using CloudClip.LocalFile;
using CloudClip.Login;
using CloudClip.Properties;

namespace CloudClip
{
    public partial class frmMain : Form
    {
        private frmMenu _frmMenu = null;
        private bool IsStartClip = false;
        private IntPtr _ClipboardViewerNext;
        private string _sTempChange;
        private NotifyIcon notifyIcon1;
        private ContextMenuStrip _ContextMenuStrip;

        public IClipProvider ClipProvider;

        public TabPage LoginControl
        {
            get { return this.tpLogin; }
            set { this.tpLogin = value; }
        }

    
        public frmMain()
        {
            InitializeComponent();
            CheckInit();
            //Login 在最前面
            LoginManager loginManager = new LoginManager();
            loginManager.Login(this);
            #region Init_icon
            this.notifyIcon1 = new NotifyIcon(this.components);
            this.notifyIcon1.Icon = Resources.Icon;
            this.notifyIcon1.Text = this.Text;
            this.Icon = Resources.Icon;
            this.notifyIcon1.MouseDoubleClick += new System.Windows.Forms.MouseEventHandler(this.notifyIcon1_MouseDoubleClick);
            this.notifyIcon1.MouseDown += new MouseEventHandler(notifyIcon1_MouseDown);
            #endregion

            #region Init_HotKey
            //註冊組合鍵事件
            HotKey hotkey1 = new HotKey(this.Handle, Keys.I, Keys.Control, Keys.Alt);
            hotkey1.OnHotkey += new HotKey.HotkeyEventHandler(hotkey1_OnHotkey);
            
            //監聽全域鍵盤事件
            KeyboardHook.GlobalKeyDown += KeyboardHook_KeyDown; 
            #endregion

            #region InitUI_設定
            this.comboBox1.Items.Add(
                new ComboBoxView("本地檔案模式", ReflectionManager.GetObjectIdentityString(new LocalFileLoginProvider())));
            this.comboBox1.SelectedItem = comboBox1.Items[0];
            #endregion
        }
        
        #region ContextMenu

        private ContextMenuStrip GetNotifyIconContextMenuStrip()
        {
            if (_ContextMenuStrip == null)
                _ContextMenuStrip = new ContextMenuStrip();
            _ContextMenuStrip.Items.Clear();

            List<ClipRow> clipList = ClipProvider.GetClipList();
            if (clipList == null)
                return _ContextMenuStrip;

            int i = 1;
            foreach (ClipRow clipRow in clipList)
            {
                ToolStripItem item = new ToolStripMenuItem();
                string sText = clipRow.ClipUnit.ToIntroduction();
                item.Text = string.Format("({0}) {1}", i, sText.Replace(Environment.NewLine, " "));
                item.ToolTipText = sText;
                item.TextAlign = ContentAlignment.MiddleLeft;
                _ContextMenuStrip.Items.Add(item);
                i++;
            }

            _ContextMenuStrip.Items.Add(new ToolStripSeparator());
            _ContextMenuStrip.Items.Add("取消");

            _ContextMenuStrip.ItemClicked += new ToolStripItemClickedEventHandler(NotifyIconContextMenuStrip_ItemClicked);
            _ContextMenuStrip.Focus();
            return _ContextMenuStrip;
        }

        private void NotifyIconContextMenuStrip_ItemClicked(object sender, ToolStripItemClickedEventArgs e)
        {
            ToolStripItem item = e.ClickedItem;
           
            if (item.Text == "取消")
                ((ContextMenuStrip)sender).Hide();

            if (item.ToolTipText == null)
                return;

            List<ClipRow> clipList = ClipProvider.GetClipList();
            ClipRow clipRow = clipList.Where(s => s.ClipUnit.ToIntroduction() == item.ToolTipText).FirstOrDefault();
            if (clipRow != null)
            {
                Clipboard.SetDataObject(clipRow.ClipUnit.ToText());
            }
        }
        #endregion

        #region Keyboard & hotkey & MouseEvent

        void notifyIcon1_MouseDown(object sender, MouseEventArgs e)
        {
            this.notifyIcon1.ContextMenuStrip = GetNotifyIconContextMenuStrip();
        }

        private void KeyboardHook_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyData == Keys.Escape)
            {
                _frmMenu.ContextMenuStrip.Hide();
            }

            if (e.KeyData == Keys.Up || e.KeyData == Keys.Down)
            {
                if (_frmMenu.ContextMenuStrip.Focused == false)
                {
                    _frmMenu.ContextMenuStrip.Focus();
                }
            }
        }
        
        private void hotkey1_OnHotkey(object sender, HotKeyEventArgs e)
        {
            if (ClipProvider == null)
                return;
            
            if (_frmMenu == null)
                _frmMenu = new frmMenu();

            _frmMenu.Show();
            _frmMenu.Activate();
            _frmMenu.ContextMenuStrip = GetNotifyIconContextMenuStrip();
            _frmMenu.ContextMenuStrip.Show(Cursor.Position.X, Cursor.Position.Y);
            _frmMenu.Hide();
        }
        #endregion
      
        private void frmMain_SizeChanged(object sender, EventArgs e)
	    {
	        if (this.WindowState == FormWindowState.Minimized)
	        {
                this.Hide();
            }
	    }

        protected void notifyIcon1_MouseDoubleClick(object sender, EventArgs e)
	    {
	        //讓Form再度顯示，並寫狀態設為Normal
	        this.Show();
	        this.WindowState = FormWindowState.Normal;
            this.Activate();
	    }

        private void frmMain_Load(object sender, System.EventArgs e)
        {
            RegisterClipboardViewer();

            IsStartClip = true;
            this.notifyIcon1.Visible = true;

        }
        
        /// <summary>
        /// Register this form as a Clipboard Viewer application
        /// </summary>
        private void RegisterClipboardViewer()
        {
            _ClipboardViewerNext = User32.SetClipboardViewer(this.Handle);
        }

        /// <summary>
        /// Remove this form from the Clipboard Viewer list
        /// </summary>
        private void UnregisterClipboardViewer()
        {
            User32.ChangeClipboardChain(this.Handle, _ClipboardViewerNext);
        }

        protected override void WndProc(ref Message m)
        {
            switch ((Msgs)m.Msg)
            {
                case Msgs.WM_DRAWCLIPBOARD:
                    OnClipboardChanged();
                    User32.SendMessage(_ClipboardViewerNext, m.Msg, m.WParam, m.LParam);
                    break;

                case Msgs.WM_CHANGECBCHAIN:
                    if (m.WParam == _ClipboardViewerNext)
                    {
                        _ClipboardViewerNext = m.LParam;
                    }
                    else
                    {
                        User32.SendMessage(_ClipboardViewerNext, m.Msg, m.WParam, m.LParam);
                    }
                    break;

                default:
                    base.WndProc(ref m);
                    break;
            }
        }
        
        private void OnClipboardChanged()
        {
            if (IsStartClip == false)
                return;

            if(ClipProvider == null || ClipProvider.CheckWorking() == false)
                return;

            IDataObject iData = Clipboard.GetDataObject();
            IClipUnit clipUnit = iData.ToClipUnit();

            if (clipUnit.ToText() == _sTempChange)
                return;

            try
            {
                if (backgroundWorker1.IsBusy == false)
                    backgroundWorker1.RunWorkerAsync(clipUnit);
            }
            catch
            {
            }
            finally
            {
                _sTempChange = clipUnit.ToText();
            }
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            IClipUnit clipUnit = e.Argument as IClipUnit;
            ClipProvider.SetClipData(clipUnit);
        }


        private void CheckInit()
        {
            Setting setting = SettingHelper.GetSetting();

            if (setting == null)
            {
                setting = new Setting();
                setting.LoginTypeString = typeof (LocalFileLoginProvider).GetObjectIdentityString();
                setting.SaveSetting();
            }
        }

        private void SyncClipList()
        {
            if (ClipProvider == null)
                return;

            ClipProvider.SyncClipList();
        }

        private void timer1_Tick(object sender, EventArgs e)
        {
           this.SyncClipList();
        }

        private void btnSetting_Click(object sender, EventArgs e)
        {
            Setting setting = SettingHelper.GetSetting();

            ComboBoxView comboBoxView = this.comboBox1.SelectedItem as ComboBoxView;

            if(comboBoxView != null)
            {
                setting.LoginTypeString = comboBoxView.Value.ToString();
            }

            setting.SaveSetting();
        }
    }

    public class ComboBoxView
    {
        public ComboBoxView(string sText, object oValue)
        {
            Text = sText;
            Value = oValue;
        }

        public string Text { get; set; }
        public object Value { get; set; }

        public override string ToString()
        {
            return Text;
        }
    }
}
